package Interfaces;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

import Auxiliary.Sequence_Type;
import DataView.AttributeInfo;
import DataView.ClassInfo;
import DataView.OperationInfo;
import DataView.ParameterInfo;
import Store.Attribute;
import Store.Class;
import Store.Operation;
import Store.Parameter;
import Store.Type;

public class CD_ManageClass 
{
	boolean modifica;
	ShowClassDiagram classDiagram;
	Class originalClass;
	CampoTesto nome = new CampoTesto();
	CampoTesto attributo = new CampoTesto();
	CampoTesto operazione = new CampoTesto();
	CampoTesto parametro = new CampoTesto();
	JPanel container;
	JPanel centerPanel;
	JPanel tabellaParametri = new JPanel();
	JTable tabAttr;
	JTable tabOper;
	JTable tabPara;
	JComboBox selectorAttr;
	JComboBox selectorOper;
	JComboBox selectorParam;
	Vector<Attribute> listaAttributi;
	Vector<Operation> listaOperazioni;
	Vector<Parameter> listaParametri= new Vector<Parameter>();
	Sequence_Type admissibleTypes;
	
	
	@SuppressWarnings("unchecked")
	public JPanel show(ShowClassDiagram cd, boolean modifica, Class clas, Sequence_Type types)
	{
		this.classDiagram=cd;
		this.modifica=modifica;
		this.originalClass=clas;
		this.admissibleTypes=types;
		
		if(modifica)
		{
			listaAttributi=(Vector<Attribute>) clas.getInfo().list_Attribute.clone();
			listaOperazioni= (Vector<Operation>) clas.getInfo().list_Operation.clone();
		}
		else
		{
			 listaAttributi = new Vector<Attribute>();
			 listaOperazioni = new Vector<Operation>();
		}
	
		container= new JPanel();
		centerPanel=new JPanel();
		centerPanel.setLayout(new BorderLayout());
		centerPanel.add(getCenterPanel(),BorderLayout.CENTER);
		container.setLayout(new BorderLayout());
		container.add(getHeaderPanel(), BorderLayout.NORTH);
		container.add(centerPanel, BorderLayout.CENTER);
		container.add(getButtonPanel(), BorderLayout.SOUTH);
		
		return container;
	}

	private JPanel getHeaderPanel() 
	{
		JPanel northPanel = new JPanel();
		northPanel.setLayout(new GridLayout(2,1));
		JLabel label = new JLabel("New Class");
		if(modifica) label.setText("Modify Class");
		label.setFont(new Font("Tahoma", Font.BOLD, 18));
		northPanel.add(label);
		
		if(modifica) 
		{
			nome.crea("Inserisci qui il nome");
			nome.setText(originalClass.getName());
			northPanel.add(nome.get());
		}
		else northPanel.add(nome.crea("Insert Class Name"));
		
		return northPanel;
	}


	private JPanel getCenterPanel() 
	{
		JPanel auxPanel=new JPanel();
		auxPanel.setLayout(new GridLayout(2,1));
		auxPanel.add(getTabellaAttributi());
		auxPanel.add(getTabellaOperazioni());
		return auxPanel;
	}

	private JPanel getTabellaAttributi() 
	{
		JPanel tabAttributi = new JPanel();
		tabAttributi.setLayout(new BorderLayout());
		JPanel buttonPanel = new JPanel();
		
		buttonPanel.setLayout(new GridLayout(1,5));
		buttonPanel.add(attributo.crea("Insert Attribute Name"));
		
		selectorAttr = new JComboBox ();
		
		int max = 0;
		if(admissibleTypes!=null) max=admissibleTypes.size();
		for(int i = 0 ; i<max ; i++)
			selectorAttr.addItem(admissibleTypes.get(i).getName());
		
		JButton addAttribute = new JButton("Add Attribute");
		addAttribute.addActionListener(new ActionListener() 
		{
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				Type t = classDiagram.updateInputCD.availableTypes.trova((String)selectorAttr.getSelectedItem());
				AttributeInfo info = new AttributeInfo();
				info.setInfo(attributo.getText(),null,t);
				Attribute a = new Attribute();
				a.mkElement(info);
				if(a.getName().length()==0)
					showMessage("Insert name for attribute");
				else{
				listaAttributi.add(a);
				attributo.clear();
				refresh(false);
				}
			}
		});
		
		JButton delAttribute = new JButton("Delete Attribute");
		
		delAttribute.addActionListener(new ActionListener()
		{
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				if(tabAttr.getSelectedRow()!=-1)
					listaAttributi.remove(tabAttr.getSelectedRow());
				refresh(false);
			}
		});
		
		
		buttonPanel.add(new JLabel("Type:",JLabel.RIGHT));
		buttonPanel.add(selectorAttr);
		buttonPanel.add(addAttribute);
		buttonPanel.add(delAttribute);
		
		tabAttributi.add(buttonPanel, BorderLayout.NORTH);
		tabAttributi.add(getTableAtt(), BorderLayout.CENTER);
		
		return tabAttributi;
	}
	
	@SuppressWarnings("serial")
	private JPanel getTableAtt() 
	{
		JPanel tabella = new JPanel();
		
		DefaultTableModel modelloRicerca = new DefaultTableModel();
		tabAttr = new JTable(modelloRicerca){public boolean isCellEditable(int rowIndex, int vColIndex){return false;}};
		modelloRicerca.addColumn("Attributes");
		tabAttr.setAutoCreateColumnsFromModel(false);								
		tabAttr.getTableHeader().setReorderingAllowed(false);
		tabAttr.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tabAttr.setFillsViewportHeight(true);
		
		int max = 0;
		if(listaAttributi!=null)
			max=listaAttributi.size();
		for (int i= 0; i<max; i++)
		{
			modelloRicerca.addRow(new Object[]{listaAttributi.get(i).getDescription()});						
		}
		
		tabella.setLayout(new BorderLayout());
		tabella.add(tabAttr.getTableHeader(), BorderLayout.NORTH);
		tabella.add(tabAttr, BorderLayout.CENTER);
		
		return tabella;
	}

	private JPanel getTabellaOperazioni() 
	{
		JPanel tabOperazioni = new JPanel();
		tabOperazioni.setLayout(new BorderLayout());
		JPanel buttonPanel = new JPanel();
		JPanel vertical1 = new JPanel();
		JPanel vertical2 = new JPanel();
		JPanel vertical3 = new JPanel();
		vertical1.setLayout(new GridLayout(2,1));
		vertical2.setLayout(new GridLayout(2,1));
		vertical3.setLayout(new GridLayout(2,2));
		buttonPanel.setLayout(new GridLayout(1,4));
		JPanel tempx=new JPanel();
		tempx.setLayout(new GridLayout(2,1));
		tempx.add(new JLabel("Operation name :",JLabel.LEFT));
		tempx.add(operazione.crea("Insert Operation Name"));
		JPanel tempx1=new JPanel();
		tempx1.setLayout(new GridLayout(2,1));
		tempx1.add(new JLabel("Parameter name :"));
		tempx1.add(parametro.crea("Insert Parameter Name"));
		vertical1.add(tempx);
		vertical1.add(tempx1);
		
		selectorOper = new JComboBox ();
		selectorParam = new JComboBox ();
		int max = 0;
		if(admissibleTypes!=null) max=admissibleTypes.size();
		selectorOper.addItem("No Return");
		for(int i = 0 ; i<max ; i++)
			{
			selectorOper.addItem(admissibleTypes.get(i).getName());
			selectorParam.addItem(admissibleTypes.get(i).getName());
			}
		JPanel temp1 = new JPanel();
		temp1.setLayout(new GridLayout(2,1));
		JPanel temp2 = new JPanel();
		temp2.setLayout(new GridLayout(2,1));
		temp1.add(new JLabel("return Type:",JLabel.LEFT));
		temp1.add(selectorOper);
		temp2.add(new JLabel("parameter Type:",JLabel.LEFT));
		temp2.add(selectorParam);
		vertical2.add(temp1);
		vertical2.add(temp2);
		

		JButton addOperation = new JButton("Add Operation");
		JButton delOperation = new JButton("Delete Operation");
		JButton addParam = new JButton("Add Parameter");
		JButton delParam = new JButton("Delete Parameter");
		addParam.addActionListener(new ActionListener()
		{			
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				Parameter p = new Parameter();
				ParameterInfo pI = new ParameterInfo();
				pI.setInfo(parametro.getText(), admissibleTypes.trova(selectorParam.getSelectedItem().toString()));
				p.mkElement(pI);
				if(p.getName().length()==0)
					showMessage("Insert a name for the parameter");
				else
				{
					listaParametri.add(p);
					parametro.clear();
					refresh(true);
				}
			}
		});
		addOperation.addActionListener(new ActionListener()
		{			
			@SuppressWarnings("unchecked")
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				Operation o = new Operation();
				OperationInfo oI = new OperationInfo();
				if(selectorOper.getSelectedIndex()==0)
						oI.setInfo(operazione.getText(), null, (Vector<Parameter>) listaParametri.clone(), null);
				else oI.setInfo(operazione.getText(), null, (Vector<Parameter>) listaParametri.clone(), admissibleTypes.trova(selectorOper.getSelectedItem().toString()));
				listaParametri.clear();
				o.mkElement(oI);
				if(o.getName().length()==0)
					showMessage("Insert a name for the operation");
				else{
				listaOperazioni.add(o);
				refresh(false);
				}
				}
		});
		delParam.addActionListener(new ActionListener()
		{
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				if(tabPara.getSelectedRow()!=-1)
					listaParametri.remove(tabPara.getSelectedRow());
				refresh(true);
			}
		});
		delOperation.addActionListener(new ActionListener()
		{
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				if(tabOper.getSelectedRow()!=-1)
					listaOperazioni.remove(tabOper.getSelectedRow());
				refresh(false);
			}
		});
		JPanel ver1 = new JPanel();
		ver1.setLayout(new GridLayout(2,1));
		ver1.add(new JLabel(" "));
		ver1.add(addOperation);
		vertical3.add(ver1);
		JPanel ver2 = new JPanel();
		ver2.setLayout(new GridLayout(2,1));
		ver2.add(new JLabel(" "));
		ver2.add(delOperation);
		vertical3.add(ver2);
		JPanel ver3 = new JPanel();
		ver3.setLayout(new GridLayout(2,1));
		ver3.add(new JLabel(" "));
		ver3.add(addParam);
		vertical3.add(ver3);
		JPanel ver4 = new JPanel();
		ver4.setLayout(new GridLayout(2,1));
		ver4.add(new JLabel(" "));
		ver4.add(delParam);
		vertical3.add(ver4);
		
		buttonPanel.add(vertical1);
		buttonPanel.add(vertical2);
		buttonPanel.add(vertical3);
		tabellaParametri = getParamTable();
		buttonPanel.add(tabellaParametri);
		
		tabOperazioni.add(buttonPanel, BorderLayout.NORTH);
		tabOperazioni.add(getTableOper(),BorderLayout.CENTER);
		
		return tabOperazioni;
	}

	@SuppressWarnings("serial")
	private Component getTableOper() 
	{
		JPanel tabella = new JPanel();
		
		DefaultTableModel modelloRicerca = new DefaultTableModel();
		tabOper = new JTable(modelloRicerca){public boolean isCellEditable(int rowIndex, int vColIndex){return false;}};
		modelloRicerca.addColumn("Operations");
		tabOper.setAutoCreateColumnsFromModel(false);								
		tabOper.getTableHeader().setReorderingAllowed(false);
		tabOper.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tabOper.setFillsViewportHeight(true);
		
		int max = 0;
		if(listaOperazioni!=null)
			max=listaOperazioni.size();
		for (int i= 0; i<max; i++)
		{
			modelloRicerca.addRow(new Object[]{listaOperazioni.get(i).getDescription()});				
		}
		
		tabella.setLayout(new BorderLayout());
		tabella.add(tabOper.getTableHeader(), BorderLayout.NORTH);
		tabella.add(tabOper, BorderLayout.CENTER);
		
		return tabella;
	}

	@SuppressWarnings("serial")
	private JPanel getParamTable() 
	{
		JPanel tabella = new JPanel();
		
		DefaultTableModel modelloRicerca = new DefaultTableModel();
		tabPara = new JTable(modelloRicerca){public boolean isCellEditable(int rowIndex, int vColIndex){return false;}};
		modelloRicerca.addColumn("Parameters List");
		tabPara.setAutoCreateColumnsFromModel(false);								
		tabPara.getTableHeader().setReorderingAllowed(false);
		tabPara.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tabPara.setFillsViewportHeight(true);
		
		int max = 0;
		if(listaParametri!=null)
			max=listaParametri.size();
		for (int i= 0; i<max; i++)
		{
			modelloRicerca.addRow(new Object[]{listaParametri.get(i).getDescription()});						
		}
		
		tabella.setLayout(new BorderLayout());
		tabella.add(tabPara.getTableHeader(), BorderLayout.NORTH);
		tabella.add(tabPara, BorderLayout.CENTER);
		
		return tabella;
	}

	private JPanel getButtonPanel() 
	{
		JPanel southPanel = new JPanel();
		
		southPanel.setLayout(new GridLayout(1,2));
		JButton ok = new JButton("Save");
		JButton cancel = new JButton("Cancel");
		
		ok.addActionListener(new ActionListener() 
		{
			@SuppressWarnings("unchecked")
			@Override public void actionPerformed(ActionEvent arg0) 
			{
				ClassInfo info = new ClassInfo();
				info.setInfo(nome.getText(), (Vector<Operation>)listaOperazioni.clone(), (Vector<Attribute>)listaAttributi.clone());
				if(info.getName().length()==0)
					showMessage("Insert the class name");
				else{
				classDiagram.container.removeAll();
				if(modifica) classDiagram.updateInputCD.updCDElement(originalClass, info);
				else classDiagram.updateInputCD.addCDElement(info);
			}}
		});
		cancel.addActionListener(new ActionListener() 
		{
			@Override public void actionPerformed(ActionEvent e) 
			{
				classDiagram.container.removeAll();
				classDiagram.showCD();
			}
		});
		
		southPanel.add(ok);
		southPanel.add(cancel);
		
		return southPanel;
	}

	public void refresh(boolean parametro)
	{
		if(parametro)
		{
			tabellaParametri.removeAll();
			tabellaParametri.add(getParamTable());
			tabellaParametri.revalidate();
		}
			
		else
		{
			centerPanel.removeAll();
			centerPanel.add(getCenterPanel(),BorderLayout.CENTER);
			centerPanel.revalidate();
		}
	}
	
	public void showMessage(String msg)
	{
		JOptionPane.showMessageDialog(container, msg, "Error", JOptionPane.ERROR_MESSAGE);
	}
}
